﻿using System.Collections.Generic;
using System.IO;
using OpenXml.Internal;
using OpenXml.Internal.IO.Packaging;
using OpenXml.Internal.IO.Zip;

namespace OpenXml.IO.Packaging
{
    public sealed class ZipPackagePart : PackagePart
    {
        private List<PieceInfo> _pieces;
        private ZipArchive _zipArchive;
        private ZipFileInfo _zipFileInfo;

        internal ZipPackagePart(Package container, ZipArchive zipArchive, PackUriHelper.ValidatedPartUri partUri, string contentType, CompressionOption compressionOption) : base(container, partUri, contentType, compressionOption)
        {
            this._zipArchive = zipArchive;
        }

        internal ZipPackagePart(Package container, ZipFileInfo zipFileInfo, PackUriHelper.ValidatedPartUri partUri, string contentType, CompressionOption compressionOption)
            : base(container, partUri, contentType, compressionOption)
        {
            this._zipArchive = zipFileInfo.ZipArchive;
            this._zipFileInfo = zipFileInfo;
        }

        internal ZipPackagePart(Package container, ZipArchive zipArchive, List<PieceInfo> pieces, PackUriHelper.ValidatedPartUri partUri, string contentType, CompressionOption compressionOption)
            : base(container, partUri, contentType, compressionOption)
        {
            this._zipArchive = zipArchive;
            this._pieces = pieces;
        }

        protected override Stream GetStreamCore(FileMode mode, FileAccess access)
        {
            if (Package.InStreamingCreation)
            {
                CompressionMethodEnum enum2;
                DeflateOptionEnum enum3;
                Package.GetZipCompressionMethodFromOpcCompressionOption(CompressionOption, out enum2, out enum3);
                return new StreamingZipPartStream(PackUriHelper.GetStringForPartUri(Uri), this._zipArchive, enum2, enum3, mode, access);
            }
            if (this._zipFileInfo != null)
            {
                return this._zipFileInfo.GetStream(mode, access);
            }
            Invariant.Assert(this._pieces != null);
            return new InterleavedZipPartStream(this, mode, access);
        }

        internal List<PieceInfo> PieceDescriptors
        {
            get
            {
                return this._pieces;
            }
        }

        internal ZipFileInfo ZipFileInfo
        {
            get
            {
                return this._zipFileInfo;
            }
        }
    }
}


